﻿
using System.Collections;
using System.Text;
using CatEars.Core;

namespace System
{
    /// <summary>
    /// System.String 的扩展
    /// </summary>
    public static partial class ExString
    {
        /// <summary>
        /// 不允许抛出异常的Strin.Format
        /// </summary>
        /// <param name="str"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static string SafeFormat(this string str, object[] args)
        {
            try
            {
                if (string.IsNullOrEmpty(str)) return string.Empty;
                if (args.IsNullOrEmpty()) return str;
                return string.Format(str, args);
            }
            catch (Exception exc)
            {
                AppEnv.Log.Warn(exc);
                return $"\"{str}\"<-({string.Join("\",\"", args)})";
            }
        }

        #region Json

        static string Indent = "    ";
        static void AppendIndent(StringBuilder sb, int count)
        {
            for (; count > 0; --count) sb.Append(Indent);
        }
        /// <summary>
        /// 美化Json
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string PrettyJson(string input)
        {
            var output = new StringBuilder();
            int depth = 0;
            int len = input.Length;
            char[] chars = input.ToCharArray();
            for (int i = 0; i < len; ++i)
            {
                char ch = chars[i];

                if (ch == '\"') // found string span
                {
                    bool str = true;
                    while (str)
                    {
                        output.Append(ch);
                        ch = chars[++i];
                        if (ch == '\\')
                        {
                            output.Append(ch);
                            ch = chars[++i];
                        }
                        else if (ch == '\"')
                            str = false;
                    }
                }

                switch (ch)
                {
                    case '{':
                    case '[':
                        output.Append(ch);
                        output.AppendLine();
                        AppendIndent(output, ++depth);
                        break;
                    case '}':
                    case ']':
                        output.AppendLine();
                        AppendIndent(output, --depth);
                        output.Append(ch);
                        break;
                    case ',':
                        output.Append(ch);
                        output.AppendLine();
                        AppendIndent(output, depth);
                        break;
                    case ':':
                        output.Append(" : ");
                        break;
                    default:
                        if (!char.IsWhiteSpace(ch))
                            output.Append(ch);
                        break;
                }
            }

            return output.ToString();
        }
        #endregion

        #region 排版
        
        /// <summary>
        /// 计算一个字符串显示出来的长度，全角当2个字符算
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static int GetDisplayLength(this string str)
        {
            if (str == null) return 0;
            //用2个char表示一个unicode字符的暂时没有处理
            int result = 0;
            foreach (char c in str)
            {
                if (c <= 255) result += 1;
                else result += 2;
            }
            return result;
        }

        /// <summary>
        /// 在字符串str左侧添加fillChar，返回处理后长度为length的字符串
        /// </summary>
        /// <param name="str"></param>
        /// <param name="length"></param>
        /// <param name="fillChar"></param>
        /// <returns></returns>
        public static string FillLeft(this string str, int length, char fillChar = ' ')
        {
            int len = length - GetDisplayLength(str);
            return Repeat(fillChar, len) + str;
        }
        /// <summary>
        /// 在字符串str右侧添加fillChar，返回处理后长度为length的字符串
        /// </summary>
        /// <param name="str"></param>
        /// <param name="length"></param>
        /// <param name="fillChar"></param>
        /// <returns></returns>
        public static string FillRight(this string str, int length, char fillChar = ' ')
        {
            int len = length - GetDisplayLength(str);
            return str + Repeat(fillChar, len);
        }
        /// <summary>
        /// 创建一个内容为chr，长度为length的字符串
        /// </summary>
        /// <param name="chr"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static string Repeat(this char chr, int length)
        {
            if (length <= 0) return string.Empty;
            char[] array = new char[length];
            for (int i = 0; i < length; i++)
            {
                array[i] = chr;
            }
            return new string(array);
        }
        /// <summary>
        /// 创建一个由times个text组成的字符串
        /// </summary>
        /// <param name="text"></param>
        /// <param name="times"></param>
        /// <returns></returns>
        public static string Repeat(this string text, int times)
        {
            if (times <= 0 || string.IsNullOrEmpty(text)) return string.Empty;
            StringBuilder str = new StringBuilder(text.Length + times);
            for (int i = 0; i < times; i++)
            {
                str.Append(text);
            }
            return str.ToString();
        }

        #endregion
    }
}
